﻿#region

using System;
using System.Diagnostics.Contracts;
using IMModel.Domain.Common;

#endregion

namespace IMModel.Domain
{
    public class IndexContext
    {
        /// <summary>
        ///   Создаёт новый экземпляр контекста расчёта индексов
        /// </summary>
        /// <param name = "term">Период</param>
        /// <param name = "filterPredicate">Функция фильтрации объектов индексной системы</param>
        /// <param name = "policy">Стратегия расчёта объёма показателей</param>
        public IndexContext(Term term, Func<IIndexObject, bool> filterPredicate, IAnswerVolumePolicy policy)
        {
            Init(term, filterPredicate, policy);
        }

        /// <summary>
        ///   Создаёт новый экземпляр контекста расчёта индексов
        /// </summary>
        /// <param name = "term">Период</param>
        /// <param name = "filterPredicate">Функция фильтрации объектов индексной системы</param>        
        public IndexContext(Term term, Func<IIndexObject, bool> filterPredicate)
        {
            Init(term, filterPredicate, DefaultAnswerVolumePolicy.Instance);
        }

        /// <summary>
        ///   Создаёт новый экземпляр контекста расчёта индексов
        /// </summary>
        /// <param name = "term">Период</param>        
        public IndexContext(Term term)
        {
            Init(term, ParticipateSectionFilter, DefaultAnswerVolumePolicy.Instance);
        }

        /// <summary>
        ///   Создаёт новый экземпляр контекста расчёта индексов
        /// </summary>
        /// <param name = "term">Период</param>        
        /// <param name = "policy">Стратегия расчёта объёма показателей</param>
        public IndexContext(Term term, IAnswerVolumePolicy policy)
        {
            Init(term, ParticipateSectionFilter, policy);
        }

        ///??? 
        static IndexContext _Current;
        /// <summary>
        ///   Получает текущий контекст расчёта индексов
        /// </summary>
        public static IndexContext Current
        {
            get { return _Current; }
        }

        /// <summary>
        ///   Получает период для которого инициирован расчёт индексов
        /// </summary>
        public Term Term { get; private set; }

        /// <summary>
        ///   Получает функцию фильтрации объектов индексной системы, включённых в расчёт индексов
        /// </summary>
        public Func<IIndexObject, bool> IndexObjectFilter { get; private set; }

        /// <summary>
        ///   Получает объект стратегии расчёта объёма показателя
        /// </summary>
        public IAnswerVolumePolicy Policy { get; private set; }

        public RespondentIndexCollection Indexes
        {
            get { return null; }
        }

        private void Init(Term term, Func<IIndexObject, bool> filterPredicate, IAnswerVolumePolicy policy)
        {
            Contract.Requires(term != null);
            Contract.Requires(filterPredicate != null);
            Contract.Requires(policy != null);
            Term = term;
            IndexObjectFilter = filterPredicate;
            Policy = policy;
            _Current = this;
        }

        private Func<IIndexObject, bool> ParticipateSectionFilter
        {
            get
            {
                return (x) =>
                {
                    SectionTerm sectionTerm = x as SectionTerm;
                    if (sectionTerm != null)
                        return sectionTerm.Participate;
                    return true;
                };
            }
        }
    }
}